package game;

import game.coord.MapGenerator;

import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;


public abstract class Abstract2DMap extends AbstractRunnable
{
    protected short cellSize = 15;
    
    private Point size;
    
    public Point getSize()
    {
        return size;
    }
    
    public void setSize(Point size)
    {
        this.size = size;
    }
    
    public void recalcSize(Dimension windowSize)
    {
        Point maxXY = calcMaxSize(new Point(windowSize));
        setSize(maxXY);
    }
    
    public static int calculateIndex(int x, int y, Point size)
    {
        if (x < 0 || x > size.getWidth())
        {
            throw new IndexOutOfBoundsException(x + " not in 0-" + size.getWidth());
        }
        if (y < 0 || y > size.getHeight())
        {
            throw new IndexOutOfBoundsException(y + " not in 0-" + size.getHeight());
        }
        int index = (size.getWidth() * y) + x;
        return index;
    }
    
    public static List<Point> getNeighborPositions(Point position, Point size)
    {
        int index = calculateIndex(position.getX(), position.getY(), size);
        List<Point> neighbors = new ArrayList<Point>();
        neighbors.add(MapGenerator.getRight(index, size));
        neighbors.add(MapGenerator.getBottom(index, size));
        neighbors.add(MapGenerator.getLeft(index, size));
        neighbors.add(MapGenerator.getTop(index, size));
        neighbors.add(MapGenerator.getBottomLeft(index, size));
        neighbors.add(MapGenerator.getBottomRight(index, size));
        neighbors.add(MapGenerator.getTopLeft(index, size));
        neighbors.add(MapGenerator.getTopRight(index, size));
        return neighbors;
    }
    
    public static Point calculatePosition(int index, Point size)
    {
        int x = 0;
        int y = 0;
        // find y
        y = index / size.getX();
        x = index - (y * size.getX());
        return new Point(x, y);
    }
    
    public Point calcMaxSize(Point windowSize)
    {
        int width = windowSize.getWidth();
        if (width % cellSize != 0)
        {
            width -= width % cellSize;
        }
        width /= cellSize;
        int height = windowSize.getHeight();
        if (height % cellSize != 0)
        {
            height -= height % cellSize;
        }
        height /= cellSize;
        return new Point(width, height);
    }
    
    public Point calcCoord(java.awt.Point p)
    {
        int x = (int) (p.getX() / cellSize);
        int y = (int) (p.getY() / cellSize);
        return new Point(x, y);
    }
    
    @Override
    public KeyListener getKeyboardControl()
    {
        return new KeyAdapter() 
        {
            @Override
            public void keyPressed(KeyEvent e)
            {
                if (isRunning() == false)
                {
                    e.consume();
                }
                short newCellSize = cellSize;
                switch (e.getKeyCode())
                {
                    case KeyEvent.VK_1:
                    {
                        newCellSize = 1;
                        break;
                    }
                    case KeyEvent.VK_2:
                    {
                        newCellSize = 2;
                        break;
                    }
                    case KeyEvent.VK_3:
                    {
                        newCellSize = 3;
                        break;
                    }
                    case KeyEvent.VK_4:
                    {
                        newCellSize = 4;
                        break;
                    }
                    case KeyEvent.VK_5:
                    {
                        newCellSize = 5;
                        break;
                    }
                    case KeyEvent.VK_6:
                    {
                        newCellSize = 6;
                        break;
                    }
                    case KeyEvent.VK_7:
                    {
                        newCellSize = 7;
                        break;
                    }
                    case KeyEvent.VK_8:
                    {
                        newCellSize = 8;
                        break;
                    }
                    case KeyEvent.VK_9:
                    {
                        newCellSize = 9;
                        break;
                    }
                    case KeyEvent.VK_0:
                    {
                        newCellSize = 10;
                        break;
                    }
                }
                if (newCellSize > 0 && newCellSize != cellSize)
                {
                    AbstractGame.log("cellSize: " + (cellSize = newCellSize));
                    requestRestart();
                }
            }
        };
    }
}
